﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace DoctorWorld
{
    public partial class VentanaPrincipal : Form
    {
        private const int ESPECTATIVADEVIDA = 150;
        private const int INDICEPRIMERAFICHA = 1;
        private const String NOFILE = "noFile"; //representa que no hay un archivo como ultima ficha abierta
        private const String EXTFICHA = ".fic"; //extension de los archivos de ficha
        private const String PATHARCHCONFIG = "data/config.dat"; //direccion del archivo de configuracion
        private const String DIRFICHAS = "data/fichas/"; //directorio de las fichas
        private const String ERRORALACTUALIZAR = "Compruebe que:\n1. Se hayan completado los campos Nombre y Apellido.\n2. El campo Documento sea solo numérico.\n3. La Fecha de Nacimiento sea solo numérica.\n4. El Número de Obra Social sea solo numérico.\n5. El Número de Historia Clínica sea solo numérico.";
        private bool alreadySaved;
        private Ficha fichaActual;
        private VentanaBuscador buscador;
        private Configurador configurador;
        private Archivador archivador;

        public VentanaPrincipal()
        {
            InitializeComponent();
            
            //Le coloca a la caja donde va el año de la persona las fechas desde la actualidad hacia atras hasta ESPECTATIVADEVIDA años
            int anoInicial = System.DateTime.Today.Year - ESPECTATIVADEVIDA;

            for (int i = System.DateTime.Today.Year; i >= anoInicial; i--)
                this.CajaAno.Items.Add(i.ToString());

            this.buscador = new VentanaBuscador();
            this.DeshabilitarEventoDeSalvar();

            this.configurador = new Configurador(PATHARCHCONFIG);

            //Cargar atributos del archivo de configuracion
            try
            {
                configurador.ReadConfig();
            }
            catch (FileOpenException e)
            {
                MessageBox.Show("No se encuentra el archivo de configuración, se cerrará la aplicación.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Application.Exit();
            }

            this.fichaActual = new Ficha();

            if (this.configurador.PathUltimaFicha != NOFILE)
            {
                //Cargar ficha actual
                this.fichaActual.BuildFromFile(this.configurador.PathUltimaFicha);

                //Cargar atributos del archivo de ficha actual
                this.MostrarFicha(this.fichaActual);
            }

            //Carga las fichas de los pacientes a memoria y agrega a cada ficha un ultimo campo con el nombre del archivo al que pertenece
            this.archivador = new Archivador();
            archivador.BuildFromDirectory(DIRFICHAS, "", INDICEPRIMERAFICHA, this.configurador.IndiceUltimaFicha, EXTFICHA);

            //Muestra la lista de pacientes en la caja listaPacientes
            this.refrescarListaPacientes();
        }

        private void MostrarFicha(Ficha ficha)
        {
            //Cargar atributos de la ficha en las cajas
            CajaNombre.Text = ficha.Nombre;
            CajaApellido.Text = ficha.Apellido;
            CajaTipoDoc.Text = ficha.TipoDoc;
            CajaNumDoc.Text = ficha.NumDoc;
            CajaDomicilio.Text = ficha.Domicilio;
            CajaTelefono.Text = ficha.Telefono;
            CajaCelular.Text = ficha.Celular;
            CajaDia.Text = ficha.DiaNacimiento;
            CajaMes.Text = ficha.MesNacimiento;
            CajaAno.Text = ficha.AnoNacimiento;
            CajaSexo.Text = ficha.Sexo;
            CajaObraSocial.Text = ficha.ObraSocial;
            CajaNOS.Text = ficha.NumObraSocial;
            CajaNumHC.Text = ficha.NumHistoriaClinica;
            CajaObservaciones.Text = ficha.Observaciones;
            this.HabilitarCampos();
            this.DeshabilitarEventoDeSalvar();
        }

        private void refrescarListaPacientes()
        {
            //Vaciar fichas de la lista de fichas de pacientes
            this.ListaPacientes.Items.Clear();

            //Si la lista de fichas esta vacia no hacer nada
            if (this.archivador.Count == 0)
                return;
            
            //Ordena la lista antes de mostrarla
            this.archivador.OrdenarPorApellidoYNumDoc();

            //Carga la lista de fichas en la caja ListaPacientes
            for (int i = 0; i < this.archivador.Count; i++)
                this.ListaPacientes.Items.Add(this.archivador.ElementAt(i).Apellido + ", " + this.archivador.ElementAt(i).Nombre + ", " + this.archivador.ElementAt(i).NumDoc);

            //Si no hay ficha actual seleccionada no se busca el que hace referencia en la lista
            if (this.configurador.PathUltimaFicha == NOFILE)
                return;
            
            //Buscar el paciente al que hace referencia la ficha seleccionada
            bool finDeBusqueda = false;
            int j = 0;
            while ((j < this.archivador.Count) && (!finDeBusqueda))
            {
                if (this.archivador.ElementAt(j).FilePath == this.fichaActual.FilePath)
                {
                    this.ListaPacientes.SetSelected(j, true);
                    finDeBusqueda = true;
                }
                j++;
            }
        }

        private void DeshabilitarCampos()
        {
            CajaApellido.ReadOnly = true;
            CajaTipoDoc.ReadOnly = true;
            CajaNumDoc.ReadOnly = true;
            CajaDomicilio.ReadOnly = true;
            CajaTelefono.ReadOnly = true;
            CajaCelular.ReadOnly = true;
            CajaDia.Enabled = false;
            CajaMes.Enabled = false;
            CajaAno.Enabled = false;
            CajaSexo.Enabled = false;
            CajaObraSocial.ReadOnly = true;
            CajaNOS.ReadOnly = true;
            CajaNumHC.ReadOnly = true;
            CajaObservaciones.ReadOnly = true;
            CajaNombre.ReadOnly = true;
        }

        private void LimpiarCampos()
        {
            CajaApellido.Text = "";
            CajaTipoDoc.Text = "";
            CajaNumDoc.Text = "";
            CajaDomicilio.Text = "";
            CajaTelefono.Text = "";
            CajaCelular.Text = "";
            CajaDia.SelectedIndex = 0;
            CajaMes.SelectedIndex = 0;
            CajaAno.SelectedIndex = 0;
            CajaSexo.SelectedIndex = 0;            
            CajaObraSocial.Text = "";
            CajaNOS.Text = "";
            CajaNumHC.Text = "";
            CajaObservaciones.Text = "";
            CajaNombre.Text = "";
        }

        private void HabilitarCampos()
        {
            CajaApellido.ReadOnly = false;
            CajaTipoDoc.ReadOnly = false;
            CajaNumDoc.ReadOnly = false;
            CajaDomicilio.ReadOnly = false;
            CajaTelefono.ReadOnly = false;
            CajaCelular.ReadOnly = false;
            CajaDia.Enabled = true;
            CajaMes.Enabled = true;
            CajaAno.Enabled = true;
            CajaSexo.Enabled = true;
            CajaObraSocial.ReadOnly = false;
            CajaNOS.ReadOnly = false;
            CajaNumHC.ReadOnly = false;
            CajaObservaciones.BackColor = SystemColors.Window;
            CajaObservaciones.ReadOnly = false;
            CajaNombre.ReadOnly = false;
        }

        private void ShouldSave(object sender, EventArgs e)
        {
            this.alreadySaved = false;
            BotonGuardar.Enabled = true;
        }

        private void DeshabilitarEventoDeSalvar()
        {
            this.alreadySaved = true;
            this.BotonGuardar.Enabled = false;
        }

        private bool EsAlfanumerico(String palabra)
        {
            for (int i = 0; i < palabra.Length; i++)
                if ((palabra[i] < 48) || (palabra[i] > 57))
                    return true;
            return false;
        }

        private void MantenerFichaActual()
        {
            //Comprobar que los campos son validos.
            if (CajaNombre.Text.Length == 0)
                throw new DatosInvalidosException();

            if (CajaApellido.Text.Length == 0)
                throw new DatosInvalidosException();

            if (CajaNumDoc.Text.Length == 0)
                throw new DatosInvalidosException();

            if (EsAlfanumerico(CajaNumDoc.Text))
                throw new DatosInvalidosException();

            if (EsAlfanumerico(CajaNOS.Text))
                throw new DatosInvalidosException();

            if (EsAlfanumerico(CajaNumHC.Text))
                throw new DatosInvalidosException();

            if ((CajaDia.Text == "Día") && (CajaMes.Text == "Mes") && (CajaAno.Text == "Año"))
            { }
            else
            {
                if (EsAlfanumerico(CajaDia.Text))
                    throw new DatosInvalidosException();

                if (EsAlfanumerico(CajaMes.Text))
                    throw new DatosInvalidosException();

                if (EsAlfanumerico(CajaAno.Text))
                    throw new DatosInvalidosException();
            }

            //Construye la ficha con los parametros actualizados
            Ficha fichaActualizada = new Ficha(new List<String> {
                CajaNombre.Text,
                CajaApellido.Text,
                CajaTipoDoc.Text,
                CajaNumDoc.Text,
                CajaDomicilio.Text,
                CajaTelefono.Text,
                CajaCelular.Text,
                CajaDia.Text,
                CajaMes.Text,
                CajaAno.Text,
                CajaSexo.Text,
                CajaObraSocial.Text,
                CajaNOS.Text,
                CajaNumHC.Text,
                CajaObservaciones.Text
            });

            //Escribe el archivo
            if (this.configurador.PathUltimaFicha == NOFILE)
            {
                this.configurador.IndiceUltimaFicha++;
                this.configurador.PathUltimaFicha = DIRFICHAS + this.configurador.IndiceUltimaFicha.ToString() + EXTFICHA;
                this.configurador.SaveConfig();
                
                //Agrega el nuevo paciente a la lista de fichas en memoria
                this.fichaActual = fichaActualizada;
                this.archivador.Add(this.fichaActual);
            }

            try
            {
                this.fichaActual.saveToFile(DIRFICHAS, this.configurador.IndiceUltimaFicha.ToString(), EXTFICHA);
            }
            catch (FileCreationException e)
            {
                MessageBox.Show("No se pudo generar el archivo para almacenar la información de la ficha.", "Error al crear la ficha", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            this.configurador.SaveConfig();
            this.refrescarListaPacientes();
        }

        private void MenuArchivoSalir_Click(object sender, EventArgs e)
        {
            DialogResult resultado;
            if (alreadySaved)
            {
                Application.Exit();
            }
            else
            {
                resultado = MessageBox.Show("¿Desea guardar los cambios en la ficha actual antes de salir?", "Guardar", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);

                if (resultado == DialogResult.No)
                {
                    Application.Exit();
                }

                if (resultado == DialogResult.Cancel)
                    return;

                if (resultado == DialogResult.Yes)
                {
                    try
                    {
                        this.MantenerFichaActual();
                    }
                    catch (DatosInvalidosException ex)
                    {
                        MessageBox.Show(ERRORALACTUALIZAR, "Error al guardar la ficha", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    Application.Exit();
                }
            }
        }

        private void MenuPacienteBuscar_Click(object sender, EventArgs e)
        {
            this.buscador.ShowDialog();
        }

        private void BotonGuardar_Click(object sender, EventArgs e)
        {
            DialogResult resultado;

            if (this.configurador.PathUltimaFicha == NOFILE)
            {
                try
                {
                    this.MantenerFichaActual();
                    this.DeshabilitarEventoDeSalvar();
                    return;
                }
                catch (DatosInvalidosException ex)
                {
                    MessageBox.Show(ERRORALACTUALIZAR, "Error al guardar la ficha", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }

            if (BotonGuardar.Enabled)
            {
                resultado = MessageBox.Show("¿Está seguro de que desea guardar los cambios?", "Guardar", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                if ((resultado == DialogResult.Yes))
                {
                    try
                    {
                        this.MantenerFichaActual();
                        this.DeshabilitarEventoDeSalvar();
                    }
                    catch (DatosInvalidosException ex)
                    {
                        MessageBox.Show(ERRORALACTUALIZAR, "Error al guardar la ficha", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                }
            }
        }

        private void DesaparecerSeleccionListaPacientes()
        {
            if (this.ListaPacientes.SelectedIndex != -1)
                this.ListaPacientes.SetSelected(this.ListaPacientes.SelectedIndex, false);
        }

        private void MenuArchivoNuevo_Click(object sender, EventArgs e)
        {
            DialogResult resultado;
            if (!alreadySaved)
            {
                resultado = MessageBox.Show("¿Desea guardar los cambios en la ficha actual antes de seguir?", "Guardar", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);

                if (resultado == DialogResult.No)
                {
                    this.LimpiarCampos();
                    this.HabilitarCampos();
                    this.configurador.PathUltimaFicha = NOFILE;
                    this.DeshabilitarEventoDeSalvar();
                    this.DesaparecerSeleccionListaPacientes();
                    return;
                }

                if (resultado == DialogResult.Cancel)
                    return;

                if (resultado == DialogResult.Yes)
                {
                    try
                    {
                        this.MantenerFichaActual();
                    }
                    catch (DatosInvalidosException ex)
                    {
                        MessageBox.Show(ERRORALACTUALIZAR, "Error al guardar la ficha", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    this.LimpiarCampos();
                    this.HabilitarCampos();
                    this.configurador.PathUltimaFicha = NOFILE;
                    this.DeshabilitarEventoDeSalvar();
                    this.DesaparecerSeleccionListaPacientes();
                    return;
                }
            }

            this.LimpiarCampos();
            this.HabilitarCampos();
            this.configurador.PathUltimaFicha = NOFILE;
            this.DeshabilitarEventoDeSalvar();
            this.DesaparecerSeleccionListaPacientes();
        }

        private void ListaPacientes_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            DialogResult resultado;
            if (!alreadySaved)
            {
                resultado = MessageBox.Show("¿Desea guardar los cambios en la ficha actual antes de seguir?", "Guardar", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);

                if (resultado == DialogResult.No)
                {
                    this.LimpiarCampos();
                    this.HabilitarCampos();
                    this.DeshabilitarEventoDeSalvar();
                    this.MostrarFicha(this.archivador.ElementAt(this.ListaPacientes.SelectedIndex));
                    this.configurador.PathUltimaFicha = this.archivador.ElementAt(this.ListaPacientes.SelectedIndex).FilePath;
                    this.configurador.SaveConfig();
                    return;
                }

                if (resultado == DialogResult.Cancel)
                    return;

                if (resultado == DialogResult.Yes)
                {
                    try
                    {
                        this.MantenerFichaActual();
                    }
                    catch (DatosInvalidosException ex)
                    {
                        MessageBox.Show(ERRORALACTUALIZAR, "Error al guardar la ficha", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    this.LimpiarCampos();
                    this.HabilitarCampos();
                    this.DeshabilitarEventoDeSalvar();
                    this.MostrarFicha(this.archivador.ElementAt(this.ListaPacientes.SelectedIndex));
                    this.configurador.PathUltimaFicha = this.archivador.ElementAt(this.ListaPacientes.SelectedIndex).FilePath;
                    this.configurador.SaveConfig();
                    return;
                }
            }

            this.LimpiarCampos();
            this.HabilitarCampos();
            this.DeshabilitarEventoDeSalvar();
            this.MostrarFicha(this.archivador.ElementAt(this.ListaPacientes.SelectedIndex));
            this.configurador.PathUltimaFicha = this.archivador.ElementAt(this.ListaPacientes.SelectedIndex).FilePath;
            this.configurador.SaveConfig();
        }
    }
}
